package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.udp.handler;


import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.constant.UdpMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;

/**
 * 客户端访客通信通道 处理器
 */
@Slf4j
public class NettyUdpClientPermeateServerTransferHandler extends SimpleChannelInboundHandler<NettyProxyMsg> {
    private final ChannelTypeAdapter channelTypeAdapter;

    public NettyUdpClientPermeateServerTransferHandler(ChannelTypeAdapter channelTypeAdapter) {
        this.channelTypeAdapter = channelTypeAdapter;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyProxyMsg) throws Exception {
        Channel channel = ctx.channel();
        channelTypeAdapter.handler(ctx, nettyProxyMsg);

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
        String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
        // 关闭访客
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
        if (nextChannel != null) {
            // 上报关闭服务端客户端真实通道
            NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
            closeVisitorMsg.setType(UdpMessageType.UDP_UDP_REPORT_CLIENT_PERMEATE_SERVER_TRANSFER_CLOSE);
            closeVisitorMsg.setVisitorId(visitorId);
            nextChannel.writeAndFlush(closeVisitorMsg);
        }

        super.channelInactive(ctx);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        if (ctx.channel().isWritable()) {
            log.debug("Channel is writable again");
            // 恢复之前暂停的操作，如写入数据
        } else {
            log.debug("Channel is not writable");
            // 暂停写入操作，等待可写状态
        }
        log.info("channelWritabilityChanged!");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
    /**
     * 心跳请求处理 * 每4秒发送一次心跳请求; *
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
        if (obj instanceof IdleStateEvent event) {
            if (IdleState.WRITER_IDLE.equals(event.state())) {  //如果写通道处于空闲状态,就发送心跳命令
                NettyProxyMsg nettyMsg = new NettyProxyMsg();
                nettyMsg.setType(UdpMessageType.UDP_TYPE_HEARTBEAT);
                ctx.writeAndFlush(nettyMsg);// 发送心跳数据
            } else if (event.state() == IdleState.WRITER_IDLE) { // 如果检测到写空闲状态，关闭连接
                // 离线、暂存通知
                ctx.close();
            }

        } else {
            super.userEventTriggered(ctx, obj);
        }
    }
}